package com.dxp.plugins;
import com.apache.api.vo.ParamsVo;
import com.apache.exception.BusinessException;
import com.apache.ius.plugin.CustomMethodPlugin;
import com.apache.tools.StrUtil;
import com.apache.tools.UUIDUtil;
import com.dxp.utils.XMLUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;

import java.util.*;

/**
 * 接收前端提交的数据（json/xml）转换格式解析后，拼装为待批量保存所需数据，执行批量入库
 * @Date 2020-04-17
 */
public class AddMsgFormatBatchPluginImpl implements CustomMethodPlugin {
	private static Logger log = Logger.getLogger(AddMsgFormatBatchPluginImpl.class);

	@Override
	public Object beforeInvoke(Map<String, Object> map) {
		String interfaceId=String.valueOf(map.get("interfaceId"));
		String dataStr=String.valueOf(map.get("dataStr"));
		String paramParent=String.valueOf(map.get("paramParent"));
		if(StrUtil.isNull(interfaceId)||StrUtil.isNull(dataStr)||"_".equals(dataStr)||StrUtil.isNull(paramParent)){
			throw new BusinessException("传入参数不能为空！");
		}
		String interfaceRMFT=String.valueOf(map.get("interfaceRMFT"));//格式是xml还是json

		log.info("-");
		log.info("转换["+interfaceRMFT+"]字符串拼装为批量保存所需数据..........start!");
		log.info("转换前原始"+interfaceRMFT+"数据："+dataStr);

		JSONObject json = null;
		if("xml".equalsIgnoreCase(interfaceRMFT)){
			try {
				Map xmlMap = XMLUtil.resolveXmlToMapList(dataStr);
				log.info("转换为Map数据："+xmlMap);
				if(xmlMap==null){
					throw new BusinessException("传入"+interfaceRMFT+"参数格式有误，请检查！");
				}
				json = JSONObject.fromObject(xmlMap);
			}catch (Exception e){
				e.printStackTrace();
				log.info("传入"+interfaceRMFT+"参数格式有误，请检查！");
				throw new BusinessException("传入"+interfaceRMFT+"参数格式有误，请检查！");
			}
		}else {
			try {
				json = JSONObject.fromObject(dataStr);
			}catch (Exception e){
				e.printStackTrace();
				log.info("传入"+interfaceRMFT+"参数格式有误，请检查！");
				throw new BusinessException("传入"+interfaceRMFT+"参数格式有误，请检查！");
			}
		}

		Map<String, String> bathcMap = getDataMapByJsonStr(json,map);
		log.info("拼装后待批量保存数据："+bathcMap);

		map.putAll(bathcMap);//追加到入参内
		return null;

	}
	@Override
	public Object doInvoke(Map<String, Object> map) {
		return null;
	}

	@Override
	public Object afterInvoke(Map<String, Object> map) {
		return null;
	}

	public static void main(String[] args) {
		AddMsgFormatBatchPluginImpl adfb = new AddMsgFormatBatchPluginImpl();
		String interfaceRMFT="xml";
		String msgType="req";
		String paramParent = "10";
		String ifNull="1";
		String paramType="2";
		String interfaceCode="abc001";
		String interfaceId="pk110236738518645211122";
		Map<String,Object> paramMap = new HashMap<>();
		paramMap.put("interfaceId",interfaceId);
		paramMap.put("paramParent",paramParent);

		String  xmlstr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><hexin>\n" +
				"  <pageName>user-list</pageName>\n" +
				"  <user>\n" +
				"    <userEname>test3</userEname>\n" +
				"    <userCname>测试用户</userCname>\n" +
				"  </user>\n" +
				"  <child>\n" +
				"    <keys>aa</keys>\n" +
				"    <keys>bb</keys>\n" +
				"  </child>\n" +
				"</hexin>\n";

		log.info("-");
		String dataStr = "{\"pageName\":\"user-list\",\"user\":{\"userEname\":\"test3\",\"userCname\":\"测试用户\"},\"child\":[{\"keys\":\"aa\"},{\"keys\":\"bb\"}]}";

		log.info("转换["+interfaceRMFT+"]字符串，拼装为批量保存所需数据..........start!");
		JSONObject json = null;
		if("xml".equalsIgnoreCase(interfaceRMFT)){
			try {
				log.info("转换前原始数据："+xmlstr);
				Map xmlMap = XMLUtil.resolveXmlToMapList(xmlstr);
				log.info("转换为Map数据："+xmlMap);
				json = JSONObject.fromObject(xmlMap);
			}catch (Exception e){
				e.printStackTrace();
				log.info("参数不是合法XML格式，请请检查！");
				return;
			}
		}else {
			try {
				json = JSONObject.fromObject(dataStr);
			}catch (Exception e){
				e.printStackTrace();
				log.info("参数不是合法JSON格式，请请检查！");
				return;
			}
			log.info("转换前原始数据："+json);
		}
		Map<String, String> jsonDataMap = adfb.getDataMapByJsonStr(json,paramMap);
		log.info("拼装后待批量保存数据："+jsonDataMap);

	}

	//获取json转换后的数据
	private Map<String,String> getDataMapByJsonStr(JSONObject json,Map<String,Object> paramMap){
		Map<String, String> addParamMap = new HashMap<>();
		if(json==null){
			return  addParamMap;
		}

		String interfaceId=String.valueOf(paramMap.get("interfaceId"));
		String paramParent=String.valueOf(paramMap.get("paramParent"));
		String interfaceRMFT=String.valueOf(paramMap.get("interfaceRMFT"));
		String msgType=String.valueOf(paramMap.get("msgType"));
		String ifNull=StrUtil.doNull(String.valueOf(paramMap.get("ifNull")),"1");
		String paramType=String.valueOf(paramMap.get("paramType"));
		String interfaceCode=String.valueOf(paramMap.get("interfaceCode"));
		String ifRowKey=StrUtil.doNull(String.valueOf(paramMap.get("ifRowKey")),"0");
		String ifUse=StrUtil.doNull(String.valueOf(paramMap.get("ifUse")),"0");

		List<Map<String,String>> datalist = new ArrayList();

		jsonToList(json,datalist,paramParent);

		String a_infoId="",a_paramEname="",a_paramParent="",a_ifSubParam="",a_interfaceId="";
		String a_interfaceRMFT="",a_msgType="",a_ifNull="",a_paramType="",a_interfaceCode="",a_ifRowKey="",a_ifUse="";

		log.info("转换后数据共计["+datalist.size()+"]条，各条明细如下：");
		if(datalist.size()>0){
			int i = 0;
			for(Map<String,String> map : datalist){
				i++;
				log.info(i+")->"+map);
				a_infoId+=addIbtachData(a_infoId, map.get("infoId"));
				a_paramEname+=addIbtachData(a_paramEname, map.get("paramEname"));
				a_paramParent+=addIbtachData(a_paramParent, map.get("paramParent"));
				a_ifSubParam+=addIbtachData(a_ifSubParam, map.get("ifSubParam"));
				a_interfaceId+=addIbtachData(a_interfaceId, interfaceId);
				a_interfaceRMFT+=addIbtachData(a_interfaceRMFT, interfaceRMFT);
				a_msgType+=addIbtachData(a_msgType, msgType);
				a_ifNull+=addIbtachData(a_ifNull, ifNull);
				a_paramType+=addIbtachData(a_paramType, paramType);
				a_interfaceCode+=addIbtachData(a_interfaceCode, interfaceCode);
				a_ifRowKey+=addIbtachData(a_ifRowKey, ifRowKey);
				a_ifUse+=addIbtachData(a_ifUse, ifUse);
			}
			addParamMap.put("dxMsgFormatSet.infoId",a_infoId);
			addParamMap.put("dxMsgFormatSet.paramEname",a_paramEname);
			addParamMap.put("dxMsgFormatSet.paramCname",a_paramEname);//同paramEname
			addParamMap.put("dxMsgFormatSet.cloumEname",a_paramEname);//同paramEname
			addParamMap.put("dxMsgFormatSet.ifSubParam",a_ifSubParam);
			addParamMap.put("dxMsgFormatSet.paramParent",a_paramParent);
			addParamMap.put("dxMsgFormatSet.interfaceId",a_interfaceId);
			addParamMap.put("dxMsgFormatSet.interfaceRMFT",a_interfaceRMFT);
			addParamMap.put("dxMsgFormatSet.msgType",a_msgType);
			addParamMap.put("dxMsgFormatSet.ifNull",a_ifNull);
			addParamMap.put("dxMsgFormatSet.paramType",a_paramType);
			addParamMap.put("dxMsgFormatSet.interfaceCode",a_interfaceCode);
			addParamMap.put("dxMsgFormatSet.ifRowKey",a_ifRowKey);
			addParamMap.put("dxMsgFormatSet.ifUse",a_ifUse);
		}
		return addParamMap;
	}


	//解析JSON至List（分父子层级）
	private void jsonToList(Object srcJson,List<Map<String,String>> list,String pid){
		if(srcJson instanceof JSONArray){
			JSONArray jsonArray = (JSONArray)srcJson;
//			for (int k = 0; k < jsonArray.size(); k++) {
//				JSONObject childJson = jsonArray.getJSONObject(k);
//				jsonToList(childJson,list,pid);
//			}
			log.info("JSONArray节点以第一个节点为准：子节点="+jsonArray);
			JSONObject childJson = (JSONObject)jsonArray.get(0);
			jsonToList(childJson,list,pid);
		}else if (srcJson instanceof JSONObject){
			JSONObject json = (JSONObject)srcJson;
			Iterator<String> iterator = json.keys();
			while (iterator.hasNext() ) {
				String key = iterator.next().toString();
				Object val = json.get(key);
				String idStr = UUIDUtil.generateId();

				if(val instanceof JSONObject || val instanceof JSONArray){
					list.add(addObjMap(idStr,key, pid,true));
					jsonToList(val,list,idStr);
				}else{
					list.add(addObjMap(idStr,key, pid,false));
				}
			}
		}
	}

	//组合关键字段的对象
	private Map<String,String> addObjMap(String infoId,String paramEname,String paramParent,boolean isChild){
		Map<String,String> maps = new HashMap<>();
		maps.put("infoId",infoId);
		maps.put("paramEname",paramEname);
		maps.put("paramParent",paramParent);
		maps.put("ifSubParam",(isChild?"1":"0"));
		return maps;
	}

	//拼接批量参数
	private String addIbtachData(String targetNameVal,String sourceNameVal){
		String newVal = StrUtil.isNull(targetNameVal) ? sourceNameVal : ("-#-" + sourceNameVal);
		return newVal;
	}

	/**
	 * 规则校验统一入口
	 * @param paramsVo
	 */
	public void run(ParamsVo paramsVo) {
		beforeInvoke(paramsVo.getParams());
	}

}

